﻿namespace Dissemination.MVC.Controllers
{
    using System.Web.Mvc;
    using Repositories;
    using ViewModels;
    using Models;
    using System.Web.Security;
    using System;
    using Dissemination.MVC.Helpers;
    using System.Collections;

    public class ReporterController : ControllerBase
    {
        protected ReporterRepository Repository = new ReporterRepository();

        #region Details

        //
        // GET: /Reporter/Details/5

        /// <summary>
        /// Returns the view associated to the details of an entity in the data source.
        /// </summary>
        /// <param name="id">The entity id.</param>
        /// <returns>Details view</returns>
        [Authorize(Roles = "Demostrator,Administrator")]
        public ActionResult Details(int id)
        {
            if (log.IsDebugEnabled) log.DebugFormat("Entering Reporter details with id={0}...", id); 
            Reporter reporter = Repository.Get(id);

            if (log.IsDebugEnabled) log.DebugFormat("Leaving Reporter details with id={0}...", id); 
            return reporter == null ? this.View("NotFound") : this.View(reporter);
        }

        #endregion

        #region New

        //
        // GET: /Reporter/Create

        /// <summary>   
        ///  Returns the view associated with an empty entity
        /// </summary>
        /// <param name="targetAreaID"></param>
        /// <returns>Create view</returns>
        [Authorize(Roles = "Administrator")]
        public ActionResult Create(int targetAreaID)
        {
            if (log.IsDebugEnabled) log.Debug("Entering Reporter creation (GET)...");
            var viewModel = new ReporterManagerViewModel
            {
                Reporter = new Reporter
                {
                    TargetArea = new TargetArea
                    {
                        TargetAreaID = targetAreaID,
                        Program = Repository.GetProgramByTargetAreaID(targetAreaID)
                    }
                },
                Genders = Repository.ListGenders(),

            };

            if (log.IsDebugEnabled) log.Debug("Leaving Reporter creation (GET)..."); 
            return View(viewModel);
        } 

        //
        // POST: /Reporter/Create

        /// <summary>
        /// Creates the specified entity.
        /// </summary>
        /// <param name="Reporter">The entity</param>
        /// <returns>Details view</returns>
        [HttpPost]
        [Authorize(Roles = "Administrator")]
        public ActionResult Create(Reporter reporter)
        {
            if (log.IsDebugEnabled) log.Debug("Entering Reporter creation (POST)...");

            int reporterGenderID = int.Parse(Request["Reporter.ReporterGenderID"]);
            int reporterTargetAreaID = int.Parse(RouteData.Values["TargetAreaID"].ToString());

            reporter.TargetArea = Repository.GetTargetAreaByID(reporterTargetAreaID);
            reporter.Gender = Repository.GetGenderByID(reporterGenderID);

            if (ModelState.IsValid)
            {
                IMembershipService membershipService = new AccountMembershipService();

                PasswordGenerator generator = new PasswordGenerator();
                string password = generator.Generate();
                
                MembershipCreateStatus createStatus = membershipService.CreateUser(
                        reporter.ReporterEmail, password, reporter.ReporterEmail);

                switch (createStatus)
                {
                    case MembershipCreateStatus.Success:
                        Roles.AddUserToRole(reporter.ReporterEmail, "Reporter");

                        MembershipUser user = membershipService.GetUserByUserName(reporter.ReporterEmail);
                        reporter.ReporterUserID = (Guid)user.ProviderUserKey;

                        Repository.Add(reporter);
                        Repository.Save();

                        NewReporterTemplateModel data = new NewReporterTemplateModel();
                        data.Password = password;
                        data.Username = reporter.ReporterEmail;
                        data.Name = reporter.ReporterName + " " + reporter.ReporterSurname;

                        Hashtable objHash = new Hashtable();
                        objHash["ext:Data"] = data;

                        MailSender.SendEmail(reporter.ReporterEmail, "ETPOD Dissemination", "NewReporter.xslt", objHash, true);

                        // TODO: Send email, update user ID and change password

                        if (log.IsDebugEnabled) log.Debug("Leaving Reporter creation (POST)...");

                        return RedirectToAction("Details", "TargetArea", new { id = reporter.TargetArea.TargetAreaID });

                    case MembershipCreateStatus.DuplicateUserName:
                        ModelState.AddModelError("Reporter.ReporterEmail", "There is another user with this email in the system");
                        break;
                    default:
                        ModelState.AddModelError("Reporter.ReporterEmail", createStatus.ToString());
                        break;
                }
            }

            var viewModel = new ReporterManagerViewModel
            {
                Reporter = reporter,
                Genders = Repository.ListGenders(),

            };

            if (log.IsDebugEnabled)
            {
                //TODO: completar Reporter_Create
            }

            return View(viewModel);
        }

        #endregion

        #region Edit

        //
        // GET: /Reporter/Edit/5

        /// <summary>
        /// Returns the view associated with the edit of an existing entity.
        /// </summary>
        /// <param name="id">The id of the entity to edit</param>
        /// <returns>Edit view</returns>
        [Authorize(Roles = "Administrator")]
        public ActionResult Edit(int id)
        {
            if (log.IsDebugEnabled) log.DebugFormat("Entering Reporter with id {0} edit (GET)...", id);
            Reporter reporter = Repository.Get(id);

            if (reporter == null)
            {
                if (log.IsErrorEnabled) log.ErrorFormat("Reporter with id={0} not found", id);
                return View("NotFound");
            };
                                
            var viewModel = new ReporterManagerViewModel
            {
                Reporter = reporter,
                Genders = Repository.ListGenders(),
            };

            if (log.IsDebugEnabled) log.DebugFormat("Leaving Reporter with id {0} edit (GET)...", id); 
            return View(viewModel);
        }

        //
        // POST: /Reporter/Edit/5

        /// <summary>
        /// Edits the specified entity.
        /// </summary>
        /// <param name="id"></param>
        /// <param name="reporter"></param>
        /// <returns></returns>
        [HttpPost]
        [Authorize(Roles = "Administrator")]
        public ActionResult Edit(int id, FormCollection collection)
        {
            if (log.IsDebugEnabled) log.DebugFormat("Entering Reporter with id {0} edit (POST)...", id);

            Reporter reporter = Repository.Get(id);
            try
            {

                int reporterGenderID = int.Parse(Request["Reporter.ReporterGenderID"]);
                int reporterTargetAreaID = int.Parse(RouteData.Values["TargetAreaID"].ToString());

                reporter.TargetArea = Repository.GetTargetAreaByID(reporterTargetAreaID);
                reporter.Gender = Repository.GetGenderByID(reporterGenderID);

                UpdateModel(reporter, "Reporter");

                Repository.Save();

                if (log.IsDebugEnabled) log.DebugFormat("Leaving Reporter with id {0} edit (POST)...", id); 
                return RedirectToAction("Details", new { id = reporter.ReporterID, TargetAreaID = reporter.TargetArea.TargetAreaID });
            }
            catch (Exception ex)
            {
                if (log.IsErrorEnabled) log.Error("Error editing Reporter", ex);

                var viewModel = new ReporterManagerViewModel
                {
                    Reporter = reporter,
                    Genders = Repository.ListGenders(),
                };

                return View(viewModel);
            }
        }

        #endregion

        #region Delete

        //
        // GET: /Reporter/Delete/5

        /// <summary>
        /// Returns the view associated with a given entity to be deleted
        /// </summary>
        /// <param name="id">The id of the existing entity</param>
        /// <returns>Delete view</returns>
        [Authorize(Roles = "Administrator")]
        public ActionResult Delete(int id)
        {
            throw new NotImplementedException();

            if (log.IsDebugEnabled) log.DebugFormat("Entering Reporter with id {0} delete (GET)...", id);
            Reporter reporter = Repository.Get(id);

            if (reporter == null)
            {
                if (log.IsErrorEnabled) log.ErrorFormat("Reporter with id={0} not found", id);
                return View("NotFound");
            }

            if (log.IsDebugEnabled) log.DebugFormat("Leaving Reporter with id {0} delete (GET)...", id);
            return View(reporter);
        }

        //
        // POST: /Reporter/Delete/5

        /// <summary>
        /// Deletes the specified entity.
        /// </summary>
        /// <param name="id">The id of the existing entity</param>
        /// <param name="confirmButton">The confirm button.</param>
        /// <returns>Deleted view</returns>
        [HttpPost]
        [Authorize(Roles = "Administrator,Reporter")]
        public ActionResult Delete(int id, string confirmButton)
        {
            throw new NotImplementedException();

            if (log.IsDebugEnabled) log.DebugFormat("Entering Reporter with id {0} delete (POST)...", id);
            Reporter reporter = Repository.Get(id);

            if (reporter == null)
            {
                if (log.IsErrorEnabled) log.ErrorFormat("Reporter with id={0} not found", id);
                return View("NotFound");
            }

            Repository.Delete(reporter);
            Repository.Save();

            if (log.IsDebugEnabled) log.DebugFormat("Leaving Reporter with id {0} delete (POST)...", id);
            return RedirectToAction("Details", "TargetArea", new { id = RouteData.Values["TargetAreaID"].ToString() });
        }

        #endregion

        #region Reset Password

        //
        // GET: /Reporter/ResetPassword

        /// <summary>   
        ///  Returns the view associated with an empty entity
        /// </summary>
        /// <param name="targetAreaID"></param>
        /// <returns>Create view</returns>
        [Authorize(Roles = "Administrator")]
        public ActionResult ResetPassword(int id, int targetAreaID)
        {
            if (log.IsDebugEnabled) log.Debug("Entering Reporter ResetPassword (GET)...");
            var model = Repository.Get(id);
            if (log.IsDebugEnabled) log.Debug("Leaving Reporter creation (GET)...");
            return View(model);
        }

        //
        // POST: /Reporter/Create

        /// <summary>
        /// Creates the specified entity.
        /// </summary>
        /// <param name="Reporter">The entity</param>
        /// <returns>Details view</returns>
        [HttpPost]
        [Authorize(Roles = "Administrator")]
        public ActionResult ResetPassword(int id)
        {
            if (log.IsDebugEnabled) log.Debug("Entering Reporter Change Password (POST)...");

            var reporter = Repository.Get(id);

            IMembershipService membershipService = new AccountMembershipService();

            string newPassword = membershipService.GetUserByUserName(reporter.ReporterEmail).ResetPassword();

            ApplicationException ex = new ApplicationException(Encryptor.EncryptStringAES(reporter.ReporterEmail + "//" + newPassword, "L'H08902-d4V1d"));

            if (log.IsDebugEnabled) log.Debug("Password changed", ex);

            NewReporterTemplateModel data = new NewReporterTemplateModel();
            data.Password = newPassword;
            data.Username = reporter.ReporterEmail;
            data.Name = reporter.ReporterName + " " + reporter.ReporterSurname;

            Hashtable objHash = new Hashtable();
            objHash["ext:Data"] = data;

            MailSender.SendEmail(reporter.ReporterEmail, "Dissemination communication", "NewPassword.xslt", objHash, true, true);


            return RedirectToAction("Details", "TargetArea", new { id = reporter.TargetArea.TargetAreaID });

        }

        #endregion

    }
}
